#pragma once

#include <any>
#include <string>
#include <vector>
namespace ecarx::transfer::lcfg {

class LocalConfigProperty {
    const int32_t identify;
    const std::string mName;
    const std::any mDefValue;
    static inline std::vector<LocalConfigProperty*> mValues;

    LocalConfigProperty(const std::string& key, const std::any& value);

  public:
    static LocalConfigProperty strConfig(const std::string key, const std::string value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty intConfig(const std::string key, const int32_t value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty uintConfig(const std::string key, const uint32_t value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty int64Config(const std::string key, const int64_t value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty uint64Config(const std::string key, const uint64_t value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty boolConfig(const std::string key, const bool value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty floatConfig(const std::string key, const float value) {
        return LocalConfigProperty(key, value);
    }

    static LocalConfigProperty doubleConfig(const std::string key, const double value) {
        return LocalConfigProperty(key, value);
    }

    const std::string name() const;
    std::any getDefValue() const;
    int32_t ordinal() const;
    static const std::vector<LocalConfigProperty*>& values();
};
#define LOCAL_CONFIG_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::strConfig(#key, value);
#define LOCAL_CONFIG_BOOLEAN_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::boolConfig(#key, value);
#define LOCAL_CONFIG_INT_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::intConfig(#key, value);
#define LOCAL_CONFIG_UINT_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::uintConfig(#key, value);
#define LOCAL_CONFIG_INT64_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::int64Config(#key, value);
#define LOCAL_CONFIG_UINT64_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::uint64Config(#key, value);
#define LOCAL_CONFIG_FLOAT_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::floatConfig(#key, value);
#define LOCAL_CONFIG_DOUBLE_PROP(key, value) \
    const LocalConfigProperty key = LocalConfigProperty::doubleConfig(#key, value);

}  // namespace ecarx::transfer::lcfg